JAVA实现图的广度优先遍历

一:广度优先遍历介绍.

      广度优先遍历(BFS),广度优先遍历是尽可能的更多的把相邻的元素都遍历了,然后在访问外层的,有点像中心开花由内到外.

     从图中任选一个顶点v,作为起始顶点.例如下图:BFS的遍历顺序是首先是V,然后是W1,W2,Y11,Y12,Y21,Y22.总是第一层访问完了,才访问第二层的,这就是二叉树的层序访问嘛.

 

 

二:广度优先遍历的实现.使用队列实现.

BFS的遍历序列如下:没有确定起始点就不唯一.这里是A是起点.

import java.util.LinkedList;
import java.util.Queue;
/**
 * title: com.lx.algorithm.graph
 * @author: lixing
 * date: 2018/10/31 17:57
 * description:广度优先遍历使用队列实现,(无向非连通图)非递归实现.
 */
public class BFSTest {

    /**
     * 存储节点信息
     */
    private char[] vertices;

    /**
     * 存储边信息(邻接矩阵)
     */
    private int[][] arcs;

    /**
     * 图的节点数
     */
    private int vexnum;

    /**
     * 记录节点是否已被遍历
     */
    private boolean[] visited;

    /**
     * 初始化
     */
    public BFSTest(int n) {
        vexnum = n;
        vertices = new char[n];
        arcs = new int[n][n];
        visited = new boolean[n];
        for (int i = 0; i < vexnum; i++) {
            for (int j = 0; j < vexnum; j++) {
                arcs[i][j] = 0;
            }
        }
    }

    /**
     * 添加边
     */
    public void addEdge(int i, int j) {
        if (i == j) {
            return;
        }
        arcs[i][j] = 1;
        arcs[j][i] = 1;
    }

    /**
     * 设置节点集
     */
    public void setVertices(char[] vertices) {
        this.vertices = vertices;
    }

    /**
     * 设置节点访问标记
     */
    public void setVisited(boolean[] visited) {
        this.visited = visited;
    }

    /**
     * 打印遍历节点
     */
    public void visit(int i) {
        System.out.print(vertices[i] + " ");
    }

    /**
     *  输出邻接矩阵
     */
    public void pritf(int[][] arcs){
        for(int i=0;i<arcs.length;i++){
            for(int j=0;j<arcs[0].length;j++){
                System.out.print(arcs[i][j]+ "\t");
            }
            System.out.println();
        }
    }

    /**
     * 实现广度优先遍历
     */
    public void bfs() {
        // 初始化所有的节点的访问标志
        for (int v = 0; v < visited.length; v++) {
            visited[v] = false;
        }
        Queue<Integer> queue = new LinkedList<Integer>();
        for (int i = 0; i < vexnum; i++) {
            if (visited[i] == false) {
                visited[i] = true;
                // 打印当前已经遍历的节点
                visit(i);
                // 添加到队列里面
                queue.add(i);
                // 只要队列不为空
                while (!queue.isEmpty()) {
                    // 出队节点,也就是这一层的节点.
                    int k = queue.poll();
                    // 遍历所有未被访问的邻接节点,放入队列
                    for (int j = 0; j < vexnum; j++) {
                        // 也就是访问这一层剩下的未被访问的节点
                        if (arcs[k][j] == 1 && visited[j] == false) {
                            visited[j] = true;
                            visit(j);
                            queue.add(j);
                        }
                    }
                }
            }
        }
        System.out.println();
        pritf(arcs);
    }

    public static void main(String[] args) {
        BFSTest g = new BFSTest(9);
        char[] vertices = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'};
        // 设置顶点集
        g.setVertices(vertices);
        // 添加边
        g.addEdge(0, 1);
        g.addEdge(0, 5);
        g.addEdge(1, 0);
        g.addEdge(1, 2);
        g.addEdge(1, 6);
        g.addEdge(1, 8);
        g.addEdge(2, 1);
        g.addEdge(2, 3);
        g.addEdge(2, 8);
        g.addEdge(3, 2);
        g.addEdge(3, 4);
        g.addEdge(3, 6);
        g.addEdge(3, 7);
        g.addEdge(3, 8);
        g.addEdge(4, 3);
        g.addEdge(4, 5);
        g.addEdge(4, 7);
        g.addEdge(5, 0);
        g.addEdge(5, 4);
        g.addEdge(5, 6);
        g.addEdge(6, 1);
        g.addEdge(6, 3);
        g.addEdge(6, 5);
        g.addEdge(6, 7);
        g.addEdge(7, 3);
        g.addEdge(7, 4);
        g.addEdge(7, 6);
        g.addEdge(8, 1);
        g.addEdge(8, 2);
        g.addEdge(8, 3);
        System.out.print("广度优先遍历(队列):");
        g.bfs();
    }
}

 运行结果:

三:深度优先对比广度优先遍历.

    1. 两种算法的时间复杂度都是一样的.

    2. 深度优先遍历涉及的辅助数据结构是栈,广度优先遍历涉及的队列.

    3. 广度优先遍历占用的内存比较多是横向元素入队的,如果这一层元素比较多,那么队内的元素就比较多,而深度优先遍历的栈内元素是深入栈的,每一条路径不会存储太对的元素,栈内元素依次出栈,占用内存减少.

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
深度优先遍历和广度优先遍历的两种常见遍历算法。 深度优先遍历(DFS)是一种递归算法,它从中的某个节点开始,首先访问该节点,然后遍历该节点的所有邻接节点,再依次对每个邻接节点进行深度优先遍历。换句话说,DFS会沿着的一条路径一直往下遍历,直到遇到没有未访问过的邻接节点为止,再返回上一级节点继续遍历其他未访问过的节点。DFS的实现一般使用递归或栈来保存待访问节点广度优先遍历(BFS)是一种队列的算法,它从中的某个节点开始,首先访问该节点,然后遍历该节点的所有邻接节点,并将这些邻接节点加入队列中。接下来从队列中取出一个节点,再依次遍历该节点的邻接节点,并将未访问过的邻接节点加入队列中,如此往复直到队列为空。BFS的实现一般使用队列来保存待访问节点。 在视频中,可以演示通过的邻接矩阵或邻接表的形式来表示,并使用Java代码来实现深度优先遍历和广度优先遍历。对于深度优先遍历,可以从中的某个节点开始递归地遍历它的邻接节点,并使用一个标记数组来记录节点是否已经访问过。对于广度优先遍历,可以使用一个队列来按照广度优先的顺序遍历中的节点,并同样使用标记数组来记录节点是否已经访问过。 通过这个视频,观众可以了解到深度优先遍历和广度优先遍历的原理和实现方法,并通过代码示例更好地理解其过程。这些算法在的遍历、路径查找等问题中应用广泛,对于理解和解决相关问题具有重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大道之简

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值